xend: passthrough: add an option pci-passthrough-strict-check
authorKeir Fraser <keir.fraser@citrix.com>
Mon, 7 Sep 2009 12:52:48 +0000 (13:52 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Mon, 7 Sep 2009 12:52:48 +0000 (13:52 +0100)
Currently when assigning device to HVM guest, we use the strict check
for HVM guest by default.(For PV guest we use loose check
automatically if necessary.)

When we assign device to HVM guest, if we meet with the co-assignment
issues or the ACS issue (see changeset 20081: 4a517458406f), we could
try changing the option to 'no' -- however, we have to realize this
may incur security issue and we can't make sure the device assignment
could really work properly even after we do this.

The option is located in /etc/xen/xend-config.sxp:
(pci-passthrough-strict-check yes)

Signed-off-by: Dexuan Cui <dexuan.cui@intel.com>
tools/examples/xend-config.sxp
tools/python/xen/util/pci.py
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/XendOptions.py
tools/python/xen/xend/server/pciif.py

index 283949e29c998448a61a906e0c80d9a1ff52d910..6c6dd2e253a28f75b329fb33f12b3560a9e510c8 100644 (file)
 #(device-create-timeout 100)
 #(device-destroy-timeout 100)
 
+# When assigning device to HVM guest, we use the strict check for HVM guest by
+# default. (For PV guest, we use loose check automatically if necessary.)
+# When we assign device to HVM guest, if we meet with the co-assignment
+# issues or the ACS issue, we could try changing the option to 'no' -- however,
+# we have to realize this may incur security issue and we can't make sure the
+# device assignment could really work properly even after we do this.
+#(pci-passthrough-strict-check yes)
index 6191f9e62b6be276be0dd70a5da4b4b833576f30..8334e3d437b7ef0872912cda3ad97bacdee6bca0 100644 (file)
@@ -1065,7 +1065,7 @@ class PciDevice:
                 ', but it is not owned by pciback or pci-stub.'
             raise PciDeviceAssignmentError(err_msg % (pci_dev, self.name))
 
-    def do_FLR(self, is_hvm):
+    def do_FLR(self, is_hvm, strict_check):
         """ Perform FLR (Functional Level Reset) for the device.
         """
         if self.dev_type == DEV_TYPE_PCIe_ENDPOINT:
@@ -1085,6 +1085,8 @@ class PciDevice:
 
                     if not is_hvm and (len(funcs) > 1):
                         return
+                    if is_hvm and not strict_check:
+                        return
 
                     self.devs_check_driver(funcs)
 
@@ -1113,6 +1115,8 @@ class PciDevice:
 
                     if not is_hvm and (len(devs) > 1):
                         return
+                    if is_hvm and not strict_check:
+                        return
 
                     self.devs_check_driver(devs)
 
index 53bdf4eaa65abf76a7794e051f7e3bbe8330a077..cf9611e212c3bc36f119d8e6da24bc9551011119 100644 (file)
@@ -311,7 +311,7 @@ def do_FLR(domid, is_hvm):
         except Exception, e:
             raise VmError("pci: failed to locate device and "+
                     "parse it's resources - "+str(e))
-        dev.do_FLR(is_hvm)
+        dev.do_FLR(is_hvm, xoptions.get_pci_dev_assign_strict_check())
 
 class XendDomainInfo:
     """An object represents a domain.
@@ -711,6 +711,9 @@ class XendDomainInfo:
         if not self.info.is_hvm():
             return
 
+        if not xoptions.get_pci_dev_assign_strict_check():
+            return
+
         # Check if there is intermediate PCIe switch bewteen the device and
         # Root Complex.
         if pci_device.is_behind_switch_lacking_acs():
index 976e8b091cbe6433a5d99d859b4eb4958924fbc1..e4a79825b76c908f844a51c887dd01deddf476a9 100644 (file)
@@ -148,6 +148,10 @@ class XendOptions:
     """Default timeout for device destruction."""
     device_destroy_timeout_default = 100
 
+    """By default, we use the strict check for HVM guest. (For PV guest, we
+    use loose check automatically if necessary."""
+    pci_dev_assign_strict_check_default = True
+
     def __init__(self):
         self.configure()
 
@@ -413,6 +417,9 @@ class XendOptions:
         return self.get_config_int("device-destroy-timeout",
                                    self.device_destroy_timeout_default)
 
+    def get_pci_dev_assign_strict_check(self):
+        return self.get_config_bool("pci-passthrough-strict-check",
+                                    self.pci_dev_assign_strict_check_default)
 
 class XendOptionsFile(XendOptions):
 
index 460a937a530e3589e6f7c0530ea1c9b075784d63..b56cf3b650a3546a509ee1b1c511215157ab305f 100644 (file)
@@ -21,6 +21,9 @@ import types
 import time
 
 from xen.xend import sxp
+from xen.xend import XendOptions
+xoptions = XendOptions.instance()
+
 from xen.xend import arch
 from xen.xend.XendError import VmError
 from xen.xend.XendLogging import log
@@ -356,6 +359,7 @@ class PciController(DevController):
         if len(pci_str_list) != len(set(pci_str_list)):
             raise VmError('pci: duplicate devices specified in guest config?')
 
+        strict_check = xoptions.get_pci_dev_assign_strict_check()
         for pci_dev in pci_dev_list:
             try:
                 dev = PciDevice(pci_dev)
@@ -365,7 +369,8 @@ class PciController(DevController):
 
             # Check if there is intermediate PCIe switch bewteen the device and
             # Root Complex.
-            if self.vm.info.is_hvm() and dev.is_behind_switch_lacking_acs():
+            if self.vm.info.is_hvm() and dev.is_behind_switch_lacking_acs() \
+                and strict_check:
                 err_msg = 'pci: to avoid potential security issue, %s is not'+\
                         ' allowed to be assigned to guest since it is behind'+\
                         ' PCIe switch that does not support or enable ACS.'
@@ -382,6 +387,8 @@ class PciController(DevController):
                 else:
                     if not self.vm.info.is_hvm():
                         continue
+                    if not strict_check:
+                        continue
 
                     funcs = dev.find_all_the_multi_functions()
                     dev.devs_check_driver(funcs)
@@ -405,6 +412,8 @@ class PciController(DevController):
                 else:
                     if not self.vm.info.is_hvm():
                         continue
+                    if not strict_check:
+                        continue
 
                     # All devices behind the uppermost PCI/PCI-X bridge must be\
                     # co-assigned to the same guest.
@@ -466,7 +475,8 @@ class PciController(DevController):
 
         # Need to do FLR here before deassign device in order to terminate
         # DMA transaction, etc
-        dev.do_FLR(self.vm.info.is_hvm())
+        dev.do_FLR(self.vm.info.is_hvm(),
+            xoptions.get_pci_dev_assign_strict_check())
 
         bdf = xc.deassign_device(fe_domid, pci_dict_to_xc_str(pci_dev))
         pci_str = pci_dict_to_bdf_str(pci_dev)